home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcr / pcr4_4.lha / DIST / loading / IncrementalLoad.c < prev    next >
C/C++ Source or Header  |  1991-01-18  |  54KB  |  1,931 lines

  1. /* begincopyright
  2.   Copyright (c) 1988 Xerox Corporation. All rights reserved.
  3.   Use and copying of this software and preparation of derivative works based
  4.   upon this software are permitted. Any distribution of this software or
  5.   derivative works must comply with all applicable United States export
  6.   control laws. This software is made available AS IS, and Xerox Corporation
  7.   makes no warranty about the software, its performance or its conformity to
  8.   any specification. Any person obtaining a copy of this software is requested
  9.   to send their name and post office or electronic mail address to:
  10.     PCR Coordinator
  11.     Xerox PARC
  12.     3333 Coyote Hill Rd.
  13.     Palo Alto, CA 94304
  14.   endcopyright */
  15.  
  16. /*
  17.  * IncrementalLoad.c
  18.  *
  19.  * Demers, January 18, 1991 8:20:01 am PST
  20.  * Aizawa, April 6, 1990 3:13:12 pm PDT
  21.  */
  22.  
  23. #include "xr/BasicTypes.h"
  24. #include "xr/Errno.h"
  25. #include "xr/Threads.h"
  26. #include "xr/ThreadsBackdoor.h"
  27. #include "xr/ThreadsTermination.h"
  28.  
  29. #include "xr/ThreadsMsg.h"
  30.  
  31. #include "xr/IncrementalLoad.h"
  32. #include "xr/IncrementalLoadPrivate.h"
  33.  
  34. #include <ctype.h>
  35. #include <fcntl.h>
  36.  
  37. #if defined(UNIX) || defined(UNIXDEBUG)
  38. #include <stdio.h>
  39. #endif
  40.  
  41. #define PREEMPTABLE_READ    1
  42.  
  43. #define DEFAULT_PBYTES_FROM_TBYTES(b) (((unsigned)(b)) >> 6)
  44.  
  45. /*
  46.  * Lock
  47.  */
  48.  
  49. XR_ILError
  50. XR_LockIncrementalLoadState(wait)
  51.     bool wait;
  52. {
  53.     XR_ILSymTab ilst = XR_ilSymTab;
  54.     XR_ILError result = NIL;
  55.  
  56.     XR_MonitorEntry(&(ilst->ilst_ml));
  57.     if( ilst->ilst_locked && (!wait) ) {
  58.         result = XR_ILMakeError(FALSE, ETIMEDOUT, "locked");
  59.         goto Out;
  60.     }
  61.     /* assert: (not locked) || wait */
  62.     while( ilst->ilst_locked ) {
  63.         int waitResult = XR_WaitCV( &(ilst->ilst_avail), &(ilst->ilst_ml) );
  64.         if( waitResult != 0 ) {
  65.             result = XR_ILMakeError( FALSE, XR_EABORTED,
  66.                     "LockIncrementalLoadState: aborted");
  67.             goto Out;
  68.         }
  69.     }
  70.     ilst->ilst_locked = TRUE;
  71. Out:
  72.     XR_MonitorExit(&(ilst->ilst_ml));
  73.     return result;
  74. }
  75.  
  76. XR_ILError
  77. XR_UnlockIncrementalLoadState()
  78. {
  79.     XR_ILSymTab ilst = XR_ilSymTab;
  80.     XR_ILError result = NIL;
  81.  
  82.     XR_MonitorEntry(&(ilst->ilst_ml));
  83.     if( ilst->ilst_locked ) {
  84.         ilst->ilst_locked = FALSE;
  85.         XR_Notify(&(ilst->ilst_avail));
  86.     } else {
  87.         result = XR_ILMakeError( FALSE, EINVAL,
  88.                 "UnlockIncrementalLoadState: not locked");
  89.     }
  90.     XR_MonitorExit(&(ilst->ilst_ml));
  91.     return result;
  92. }
  93.  
  94.  
  95. /*
  96.  *
  97.  * ILFile table stuff
  98.  *
  99.  */
  100.  
  101. static char *
  102. XR_CompressSlashesInPlace(path)
  103.     char *path;
  104. {
  105.     char *from;
  106.     char *to;
  107.     char c;
  108.  
  109.     from = to = path;
  110.     for(;;) {
  111.         c = (*to++ = *from++);
  112.         if( c == 0 ) break;
  113.         if( c == '/' ) {
  114.             while( *from == '/' ) from++;
  115.         }
  116.     }
  117.     to -= 2;
  118.     if( (to > path) && (*to == '/') ) *to = 0;
  119.     return path;
  120. }
  121.  
  122.  
  123. static XR_ILFileTabEntry
  124. XR_ILCreateILFTE(ilst, fName, fOffset)
  125.     XR_ILSymTab ilst;
  126.     char *fName;
  127.     unsigned fOffset;
  128. {
  129.     XR_ILFileTabEntry ilfte;
  130.  
  131.     ilfte = (XR_ILFileTabEntry) XR_PZcalloc(
  132.             ilst->ilst_zone, sizeof(struct XR_ILFileTabEntryRep), 1);
  133.     if( ilfte == NIL ) return NIL;
  134.  
  135.     if( fName != NIL ) {
  136.         extern char *(XR_ExpandPath());
  137.         char *nameCopy = XR_ExpandPath(fName);
  138.         if( nameCopy == NIL ) return NIL;
  139.         if( nameCopy == fName ) {
  140.             nameCopy = (char *)
  141.                 XR_PZmalloc( ilst->ilst_zonePtrFree, strlen(fName)+1 );
  142.             if( nameCopy == NIL ) return NIL;
  143.             strcpy(nameCopy, fName);
  144.         }
  145.         ilfte->ilfte_ilfe.ilfe_fName = XR_CompressSlashesInPlace(nameCopy);
  146.     } else {
  147.         ilfte->ilfte_ilfe.ilfe_fName = "";
  148.     }
  149.  
  150.     ilfte->ilfte_ilfe.ilfe_fOffset = fOffset;
  151.     ilfte->ilfte_ilfe.ilfe_seqNum = ilst->ilst_seqNum;
  152.     ilst->ilst_seqNum += 1;
  153.     return ilfte;
  154. }
  155.  
  156.  
  157. XR_ILFileEntry
  158. XR_ILGetPrevFileEntry(ilfe)
  159.     XR_ILFileEntry ilfe;
  160. {
  161.  
  162.     if( ilfe == NIL ) {
  163.         return ((XR_ILFileEntry)(XR_ilSymTab->ilst_ilfte));
  164.     } else {
  165.         return ( (XR_ILFileEntry) (((XR_ILFileTabEntry)(ilfe))->ilfte_prev) );
  166.     }
  167. }
  168.  
  169.  
  170. /* static */ void
  171. XR_ILAddVersionStamp(ilfe, vMagic, vLen, vStamp)
  172.     XR_ILFileEntry ilfe;
  173.     unsigned vMagic;
  174.     unsigned vLen;
  175.     char * vStamp;
  176. {
  177.     ilfe->ilfe_vMagic = vMagic;
  178.     ilfe->ilfe_vLen = vLen;
  179.     ilfe->ilfe_vStamp = vStamp; 
  180.     ilfe->ilfe_vMagic = vMagic;
  181. }
  182.  
  183.  
  184. XR_ILFileEntry
  185. XR_ILAddVersionStampUsingPC(pc, vMagic, vLen, vStamp)
  186.     caddr_t pc;
  187.     unsigned vMagic;
  188.     unsigned vLen;
  189.     char * vStamp;
  190. {
  191.     XR_ILSymTabEntry ilste;
  192.     XR_ILFileEntry ilfe;
  193.  
  194.     ilste = (XR_ILSymTabEntry) XR_ILLookupSymEntryByValue(pc);
  195.     if( ilste == NIL ) return NIL;
  196.     ilfe = ilste->ilste_ilse.ilse_ilfe;
  197.     XR_ILAddVersionStamp(ilfe, vMagic, vLen, vStamp);
  198.     return ilfe;
  199. }
  200.  
  201.  
  202.  
  203. /*
  204.  * Default GC root stuff
  205.  */
  206.  
  207.  
  208. /*
  209. ??? INTERIM ???
  210. When we commit, we tell the GC (once) about all the
  211. committed roots.  This won't allow us to unload, but currently we
  212. can't do that anyway ...
  213. */
  214.  
  215. static void
  216. XR_ILGCCallback(seg, data)
  217.     XR_Seg seg;
  218.     XR_Pointer data;
  219. {
  220.     extern void XR_add_data_list(/* XR_Pointer low, hi */); /* from GC.h */
  221.  
  222.     if( seg->seg_addr == NIL ) XR_Panic("ILGCCallBack 0");
  223.     if( data != NIL ) XR_Panic("ILGCCallBack 1");
  224.     XR_add_data_list( seg->seg_addr, seg->seg_addr + seg->seg_bytes );
  225. }
  226.  
  227.  
  228. static void
  229. XR_ILTellCollectorAboutRoots(ilst, ilfte)
  230.     XR_ILSymTab ilst;
  231.     XR_ILFileTabEntry ilfte;
  232. {
  233.     if( ilfte->ilfte_gcRootEnumerator != NIL ) {
  234.         (*(ilfte->ilfte_gcRootEnumerator))(
  235.                 XR_ILGCCallback,
  236.                 NIL, 
  237.                 ilfte->ilfte_gcRootEnumeratorData
  238.         );
  239.     } else {
  240.         XR_ConsoleMsg( "ILTellCollectorAboutRoots botch, file %s\n",
  241.             ilfte->ilfte_ilfe.ilfe_fName );
  242.     }
  243. }
  244.  
  245. /*
  246. ??? END of INTERIM stuff
  247. */
  248.  
  249.  
  250. static void
  251. XR_ILDefaultBootFileGCRootEnumerator(gcCallback, gcCallbackData, data)
  252.     XR_GCRootCallback gcCallback /*(XR_Seg seg, XR_Pointer data)*/ ;
  253.     XR_Pointer gcCallbackData;
  254.     XR_Pointer data;
  255. {
  256.     if( XR_sysArea->sa_sharedDataSeg.seg_bytes > 0 )
  257.         (*gcCallback)( &(XR_sysArea->sa_sharedDataSeg), gcCallbackData );
  258. #ifdef XXXX
  259.     if( XR_sysArea->sa_sharedBSSSeg.seg_bytes > 0 )
  260.         (*gcCallback)( &(XR_sysArea->sa_sharedBSSSeg), gcCallbackData );
  261.     if( XR_sysArea->sa_sharedCommonSeg.seg_bytes > 0 )
  262.         (*gcCallback)( &(XR_sysArea->sa_sharedCommonSeg), gcCallbackData );
  263. #endif
  264. }
  265.  
  266.  
  267. static void
  268. XR_ILDefaultGCRootEnumerator(gcCallback, gcCallbackData, data)
  269.     XR_GCRootCallback gcCallback /*(XR_Seg seg, XR_Pointer data)*/ ;
  270.     XR_Pointer gcCallbackData;
  271.     XR_Pointer data;
  272. {
  273.     struct XR_SegRep seg;
  274.     XR_ILFileTabEntry ilfte = ((XR_ILFileTabEntry)(data));
  275. #   define CondCallback(addr,bytes) if( (bytes) > 0 ) { \
  276.         seg.seg_addr = ((XR_Pointer)(addr)); seg.seg_bytes = (bytes); \
  277.         (*gcCallback)( &seg, gcCallbackData ); }
  278.  
  279.     CondCallback(ilfte->ilfte_ilfe.ilfe_dAddr, ilfte->ilfte_ilfe.ilfe_dBytes);
  280.     CondCallback(ilfte->ilfte_ilfe.ilfe_bAddr, ilfte->ilfte_ilfe.ilfe_bBytes);
  281.     CondCallback(ilfte->ilfte_ilfe.ilfe_cAddr, ilfte->ilfte_ilfe.ilfe_cBytes);
  282.  
  283. #   undef CondCallback
  284. }
  285.  
  286.  
  287. void
  288. XR_ILSetGCRootEnumerator(ilst, ilfte, gcRootEnumerator, gcRootEnumeratorData)
  289.     XR_ILSymTab ilst;
  290.     XR_ILFileTabEntry ilfte;
  291.     XR_GCRootEnumerator gcRootEnumerator;
  292.     XR_Pointer gcRootEnumeratorData;
  293. {
  294.     ilfte->ilfte_gcRootEnumerator = NIL;
  295.     ilfte->ilfte_gcRootEnumeratorData = gcRootEnumeratorData;
  296.     ilfte->ilfte_gcRootEnumerator = gcRootEnumerator;
  297. }
  298.  
  299.  
  300. /*
  301.  *
  302.  * Symbol Table
  303.  *
  304.  * Hash table by name of text or external symbols.
  305.  * Skiplist by value of (text, external data, external bss) symbols.
  306.  *
  307.  */
  308.  
  309. #define XR_ILST_INIT_NUM_HDRS    (8*1024) /* must be power of 2 */
  310. #define XR_ILIndexFromHash(hash, numHdrs)  ((hash)&((numHdrs) - 1))
  311.  
  312. #define HEIGHTMASK    0x3
  313. #define HEIGHTSHIFT    2
  314. #define MAXHEIGHT    16
  315.  
  316. static unsigned
  317. XR_ILHeightFromNum(num)
  318.     unsigned num;
  319. {
  320.     int i = 0;
  321.  
  322.     for(;;) {
  323.         if( ((++i) == MAXHEIGHT) || ((num & HEIGHTMASK) != 0) ) return i;
  324.         num >>= HEIGHTSHIFT;
  325.     }
  326. }
  327.  
  328. #define CASE_MASK 0137 /* collapses upper & lower case, other effects too! */
  329.  
  330. unsigned
  331. XR_ILHashFromSym(sym)
  332.     char *sym;
  333. {
  334.     unsigned hash = 0;
  335.     unsigned c;
  336.  
  337.     if( sym == NIL ) return 0;
  338.     for(;;) {
  339.         switch(c = *sym++) {
  340.             case 0:
  341.             case '.':
  342.             case '*':
  343.                 return hash;
  344.         }
  345.         hash = (hash * 5) + (c & CASE_MASK);
  346.     }
  347. }
  348.  
  349.  
  350.  
  351. bool
  352. XR_StrMatchCase(str, pat, caseSensitive)
  353.     char *str;
  354.     char *pat;
  355.     bool caseSensitive;
  356. {
  357.     char sc, pc;
  358.  
  359.     for(;;) {
  360.         if( (pc = *pat++) == '*' ) return TRUE;
  361.         if( (sc = *str++) == 0 ) return ( pc == 0 );
  362.         if( sc != pc ) {
  363.             if( caseSensitive || (pc == 0) ) return FALSE;
  364.             if( isascii(sc) && isupper(sc) ) sc = tolower(sc);
  365.             if( isascii(pc) && isupper(pc) ) pc = tolower(pc);
  366.             if( sc != pc ) return FALSE;
  367.         }
  368.     }
  369. }
  370.  
  371.  
  372.  
  373. static bool
  374. XR_ILTypeIsWanted(theType, wantedTypes, ignoredClasses)
  375.     unsigned theType;
  376.     unsigned wantedTypes;
  377.     unsigned ignoredClasses;
  378. {
  379.     if( theType & ILSE_EXT ) {
  380.         if( ignoredClasses & IGNORE_EXTERNAL ) return FALSE;
  381.     } else {
  382.         if( ignoredClasses & IGNORE_INTERNAL ) return FALSE;
  383.     }
  384.     if( wantedTypes == WANT_ALL_TYPES ) return TRUE;
  385.     return ((theType & ILSE_TYPE) == (wantedTypes & ILSE_TYPE));
  386. }
  387.  
  388.  
  389. static XR_ILSymTabEntry
  390. XR_ILGetMatchingSTEByName(
  391.     ilst, ilste, pat, hash, ulCase, wantedTypes, ignoredClasses, numToSkip
  392. )
  393.     XR_ILSymTab ilst;
  394.     XR_ILSymTabEntry ilste;
  395.     char *pat;
  396.     unsigned hash;
  397.     bool ulCase;
  398.     unsigned wantedTypes;
  399.     unsigned ignoredClasses;
  400.     int numToSkip;
  401. {
  402.     if( ilste == NIL ) {
  403.         unsigned index = XR_ILIndexFromHash(hash, ilst->ilst_numHdrs);
  404.         ilste = ilst->ilst_hdrs[index];
  405.         if( numToSkip > 0 ) numToSkip -= 1;
  406.         else if( numToSkip < 0 ) numToSkip += 1;
  407.         /* else (numToSkip == 0) numToSkip = 0; */
  408.     }
  409.  
  410.     for(;;) {
  411.         if( ilste == NIL ) break;
  412.         if( ilste->ilste_hash == hash ) {
  413.             if( XR_ILTypeIsWanted(ilste->ilste_ilse.ilse_type,
  414.                         wantedTypes, ignoredClasses) ) {
  415.                 if( XR_StrMatchCase(ilste->ilste_ilse.ilse_name,
  416.                         pat, ulCase) ) {
  417.                     if( numToSkip == 0 ) break;
  418.                     else if( numToSkip > 0 ) numToSkip -= 1;
  419.                     else /* numToSkip < 0 */ numToSkip += 1;
  420.                 }
  421.             }
  422.         }
  423.         ilste = ilste->ilste_symNext;
  424.     }
  425.     return ilste;
  426. }
  427.  
  428.  
  429.  
  430. XR_ILSymEntry
  431. XR_ILGetMatchingSymEntryByName(
  432.     ilse, pattern, caseSensitive, wantedTypes, ignoredClasses, numToSkip
  433.     XR_ILSymEntry ilse;
  434.     char *pattern;
  435.     bool caseSensitive;
  436.     unsigned wantedTypes;
  437.     unsigned ignoredClasses;
  438.     int numToSkip;
  439. {
  440.     unsigned hash;
  441.     XR_ILSymTabEntry ilste = ((XR_ILSymTabEntry)(ilse));
  442.  
  443.     if( pattern == NIL ) {
  444.         if( ilste == NIL ) return NIL;
  445.         pattern = ilste->ilste_ilse.ilse_name;
  446.         hash = ilste->ilste_hash;
  447.     } else {
  448.         hash = XR_ILHashFromSym(pattern);
  449.     }
  450.         
  451.     return ((XR_ILSymEntry)
  452.         XR_ILGetMatchingSTEByName(
  453.             XR_ilSymTab,
  454.             ilste,
  455.             pattern,
  456.             hash,
  457.             caseSensitive,
  458.             wantedTypes,
  459.             ignoredClasses,
  460.             numToSkip
  461.         )
  462.     );
  463. }
  464.  
  465.  
  466. /* could be obsolete, but used internally: */
  467.  
  468. /* static */
  469. XR_ILSymTabEntry
  470. XR_ILLookupSTEByName(ilst, sym, hash, ulCase, extOnly)
  471.     XR_ILSymTab ilst;
  472.     char *sym;
  473.     unsigned hash;
  474.     bool ulCase;
  475.     bool extOnly;
  476. {
  477.     unsigned index;
  478.     XR_ILSymTabEntry ilste;
  479.  
  480.     index = XR_ILIndexFromHash(hash, ilst->ilst_numHdrs);
  481.     ilste = ilst->ilst_hdrs[index];
  482.     for(;;) {
  483.         if( ilste == NIL ) break;
  484.         if( ilste->ilste_hash == hash ) {
  485.             if( (!extOnly) || (ilste->ilste_ilse.ilse_type & ILSE_EXT) ) {
  486.                 if( XR_StrMatchCase(ilste->ilste_ilse.ilse_name, sym, ulCase))
  487.                     break;
  488.             }
  489.         }
  490.         ilste = ilste->ilste_symNext;
  491.     }
  492.     return ilste;
  493. }
  494.  
  495.  
  496. static XR_ILSymTabEntry
  497. XR_ILLookupSTEByValue(val)
  498.     unsigned val;
  499. {
  500.     XR_ILSymTabEntry p, q;
  501.     unsigned h1;
  502.  
  503.     p = XR_ilSymTab->ilst_left;
  504.     if( (h1 = XR_ilSymTab->ilst_maxHeight) > 0 ) {
  505.         h1 -= 1;
  506.         for(;;) {
  507.             q = p->ilste_valNext[h1];
  508.             if( (q == NIL) || (q->ilste_ilse.ilse_value > val) ) {
  509.                 if( h1 == 0 ) break;
  510.                 h1 -= 1;
  511.             } else {
  512.                 p = q;
  513.             }
  514.         }
  515.     }
  516.     return( p );
  517. }
  518.  
  519.  
  520. XR_ILSymEntry
  521. XR_ILGetMatchingSymEntryByValue(
  522.     ilse, val, wantedTypes, ignoredClasses, numToSkip
  523. )
  524.     XR_ILSymEntry ilse;
  525.     unsigned val;
  526.     unsigned wantedTypes;
  527.     unsigned ignoredClasses;
  528.     int numToSkip;
  529. {
  530.     XR_ILSymTabEntry p, left;
  531.     XR_ILSymTabEntry ilste;
  532.  
  533.     ilste = ( (ilse != NIL)
  534.             ? ((XR_ILSymTabEntry)(ilse))
  535.             : XR_ILLookupSTEByValue(val) );
  536.  
  537.     if( ilste == NIL ) /* can't happen */ {
  538. XR_ConsoleMsg("ILGetMatchingSymEntryByValue botch 0\n");
  539.         return NIL;
  540.     }
  541.  
  542.     /* What if the type of *ilse is not in wantedTypes?  Well, ... */
  543.     if( !(XR_ILTypeIsWanted(ilste->ilste_ilse.ilse_type,
  544.             wantedTypes, ignoredClasses)) ) {
  545.         if( numToSkip <= 0 ) numToSkip -= 1;
  546.     }
  547.  
  548.     while( numToSkip < 0 ) {
  549.         left = ((ilste->ilste_ilse.ilse_value == 0)
  550.                 ? XR_ilSymTab->ilst_left
  551.                 : XR_ILLookupSTEByValue(ilste->ilste_ilse.ilse_value-1));
  552.         if( left == ilste ) return NIL;
  553.         for( p = left; p != ilste; p = p->ilste_valNext[0] ) {
  554.             if( XR_ILTypeIsWanted(p->ilste_ilse.ilse_type,
  555.                     wantedTypes, ignoredClasses) )
  556.                 numToSkip += 1;
  557.         }
  558.         ilste = left;
  559.     }
  560.  
  561.     for(;;) {
  562.         if( ilste == NIL ) return NIL;
  563.         if( XR_ILTypeIsWanted(ilste->ilste_ilse.ilse_type,
  564.                 wantedTypes, ignoredClasses) ) {
  565.             if( numToSkip == 0 ) return ((XR_ILSymEntry)(ilste));
  566.             numToSkip -= 1;
  567.         }
  568.         ilste = ilste->ilste_valNext[0];
  569.     }
  570. }
  571.  
  572.  
  573.  
  574. static void
  575. XR_ILGrowST(ilst)
  576.     XR_ILSymTab ilst;
  577. {
  578.     int i, n, newN;
  579.     XR_ILSymTabEntry *newHdrs, *pfrom, *pto;
  580.     XR_ILSymTabEntry t, revList;
  581.  
  582.     n = ilst->ilst_numHdrs;
  583.     newN = n + n;
  584.     newHdrs = (XR_ILSymTabEntry *) XR_calloc(
  585.             2 * n * sizeof(XR_ILSymTabEntry), 1 );
  586.     if( newHdrs == NIL ) return; /* doesn't hurt to fail here ... */
  587.     for( i = 0; i < n; i++ ) {
  588.         pfrom = ilst->ilst_hdrs + i;
  589.         revList = NIL;
  590.         while( *pfrom != NIL ) {
  591.             t = *pfrom;
  592.             *pfrom = t->ilste_symNext;
  593.             t->ilste_symNext = revList;
  594.             revList = t;
  595.         }
  596.         while( revList != NIL ) {
  597.             t = revList;
  598.             revList = t->ilste_symNext;
  599.             pto = newHdrs + XR_ILIndexFromHash(t->ilste_hash, newN);
  600.             t->ilste_symNext = *pto;
  601.             *pto = t;
  602.         }
  603.     }
  604.     ilst->ilst_hdrs = newHdrs;
  605.     ilst->ilst_numHdrs = newN;
  606. }
  607.  
  608.  
  609. static void
  610. XR_ILInsertSTE(ilst, ilste)
  611.     XR_ILSymTab ilst;
  612.     XR_ILSymTabEntry ilste;
  613. {
  614.     unsigned index, h1;
  615.     XR_ILSymTabEntry p, q;
  616.  
  617.     if( ilst->ilst_numEntries >= ilst->ilst_numHdrs ) XR_ILGrowST(ilst);
  618.     index = XR_ILIndexFromHash(ilste->ilste_hash, ilst->ilst_numHdrs);
  619.     ilste->ilste_symNext = ilst->ilst_hdrs[index];
  620.     ilst->ilst_hdrs[index] = ilste;
  621.     /* insert entry in new sym list */
  622.         ilste->ilste_valNext[0] = NIL;
  623.         if( ilst->ilst_newSymsTl == NIL ) {
  624.             ilst->ilst_newSymsHd = ilste;
  625.         } else {
  626.             ilst->ilst_newSymsTl->ilste_valNext[0] = ilste;
  627.         }
  628.         ilst->ilst_newSymsTl = ilste;
  629.     ilst->ilst_numEntries += 1;
  630. }
  631.  
  632.  
  633. static void
  634. XR_ILInsertSTEByValue(ilst, ilste)
  635.     XR_ILSymTab ilst;
  636.     XR_ILSymTabEntry ilste;
  637. {
  638.     unsigned index, h1;
  639.     XR_ILSymTabEntry p, q;
  640.     unsigned newHeight;
  641.  
  642.     newHeight = ilst->ilst_maxHeight;
  643.     ilst->ilst_maxHeight = 1;
  644.     if( newHeight < ilste->ilste_height ) newHeight = ilste->ilste_height;
  645.  
  646.     h1 = newHeight - 1;
  647.     p = ilst->ilst_left;
  648.     for(;;) {
  649.         q = p->ilste_valNext[h1];
  650.         if( (q == NIL)
  651.                 || (q->ilste_ilse.ilse_value > ilste->ilste_ilse.ilse_value) ) {
  652.             if( h1 < ilste->ilste_height ) {
  653.                 ilste->ilste_valNext[h1] = q;
  654.                 p->ilste_valNext[h1] = ilste;
  655.                 if( h1 == 0 ) break;
  656.             }
  657.             h1 -= 1;
  658.         } else {
  659.             p = q;
  660.         }
  661.     }
  662.     ilst->ilst_maxHeight = newHeight;
  663. }
  664.  
  665.  
  666. static XR_ILSymTabEntry
  667. XR_ILMakeSTE(ilst, sym, hash, symType, symValue, symSize)
  668.     XR_ILSymTab ilst;
  669.     char *sym;
  670.     unsigned hash;
  671.     unsigned symType;
  672.     unsigned symValue;
  673.     unsigned symSize;
  674. {
  675.     unsigned height;
  676.     XR_ILSymTabEntry ilste;
  677.     static unsigned seqnum = 1;
  678.         /* there COULD be interference between processors, but this is okay */
  679.  
  680.     height = XR_ILHeightFromNum(seqnum++);
  681.     ilste = (XR_ILSymTabEntry) XR_PZcalloc(
  682.             ilst->ilst_zonePtrFree, XR_ILSymTabEntryBytes(height), 1 );
  683.     if( ilste == NIL ) {
  684.         XR_ILSetError(ilst, TRUE, ENOMEM, "ILMakeSTE: no memory");
  685.         return NIL;
  686.     }
  687.     ilste->ilste_ilse.ilse_name = sym;
  688.     ilste->ilste_ilse.ilse_type = symType;
  689.     ilste->ilste_ilse.ilse_value = symValue;
  690.     ilste->ilste_ilse.ilse_size = symSize;
  691.     ilste->ilste_ilse.ilse_ilfe = (XR_ILFileEntry)(ilst->ilst_ilfte);
  692.     ilste->ilste_hash = hash;
  693.     ilste->ilste_height = height;
  694.     return ilste;
  695. }
  696.  
  697.  
  698.  
  699. static void
  700. XR_ILDeleteSTE(ilst, ilste)
  701.     XR_ILSymTab ilst;
  702.     XR_ILSymTabEntry ilste;
  703. {
  704.     unsigned index;
  705.     int h1;
  706.     XR_ILSymTabEntry p, q;
  707.     unsigned newMaxHeight;
  708.  
  709.     /* delete from hash table */
  710.         index = XR_ILIndexFromHash(ilste->ilste_hash, ilst->ilst_numHdrs);
  711.         p = ilst->ilst_hdrs[index];
  712.         if( p == ilste ) {
  713.             ilst->ilst_hdrs[index] = ilste->ilste_symNext;
  714.         } else {
  715.             while( p->ilste_symNext != ilste ) p = p->ilste_symNext;
  716.             p->ilste_symNext = p->ilste_symNext->ilste_symNext;
  717.         }
  718.         ilst->ilst_numEntries -= 1;
  719.  
  720.     /* delete from skip list if present */
  721.     /* n.b. code must work with multiple instances of same key! */
  722.         if( (newMaxHeight = ilst->ilst_maxHeight) == 0 )
  723.             goto NotInSkipList;
  724.         ilst->ilst_maxHeight = 1;
  725.         h1 = newMaxHeight - 1;
  726.         p = ilst->ilst_left;
  727.         for(;;) {
  728.             q = p->ilste_valNext[h1];
  729.             if( (q == NIL) || (q->ilste_ilse.ilse_value
  730.                     >= ilste->ilste_ilse.ilse_value) ) {
  731.                 if( h1 < ilste->ilste_height ) break;
  732.                 h1 -= 1;
  733.             } else {
  734.                 p = q;
  735.             }
  736.         }
  737.         /* ilste is to right of p in skip list, if present at all */
  738.         /* h1 == ilste->ilste_height - 1, if ilste present at all */
  739.         for(;;) {
  740.             q = p->ilste_valNext[h1];
  741.             if( q == ilste ) {
  742.                 break;
  743.             } else if( (q == NIL) || (q->ilste_ilse.ilse_value
  744.                     > ilste->ilste_ilse.ilse_value) ) {
  745.                 goto NotInSkipList;
  746.             } else {
  747.                 p = q;
  748.             }
  749.         }
  750.         while( h1 >= 0 ) {
  751.             p->ilste_valNext[h1] = q->ilste_valNext[h1];
  752.             h1 -= 1;
  753.         }
  754.         while( (newMaxHeight > 1)
  755.                 && (ilst->ilst_left->ilste_valNext[newMaxHeight-1] == NIL) ) {
  756.             newMaxHeight -= 1;
  757.         }
  758.         
  759.     NotInSkipList: ;
  760.         ilst->ilst_maxHeight = newMaxHeight;
  761.  
  762. }
  763.  
  764. /*
  765.  *
  766.  * Registration stuff
  767.  *
  768.  * Exported to IncrementalLoadPrivate.h
  769.  *
  770.  */
  771.  
  772.  
  773. int
  774. XR_RegisterIncrementalLoadProc(proc, data, nMagics, magics)
  775.     XR_ILReaderProc proc;
  776.     XR_Pointer data;
  777.     int nMagics;
  778.     unsigned *magics;
  779. {
  780.     XR_ILRegistration ilr;
  781.     int i;
  782.  
  783.     ilr = (XR_ILRegistration) XR_malloc(XR_ILRegistrationBytes(nMagics));
  784.     if( ilr == NIL ) {
  785.         XR_SetErrno(ENOMEM);
  786.         return (-ENOMEM);
  787.     }
  788.     ilr->ilr_proc = proc;
  789.     ilr->ilr_data = data;
  790.     ilr->ilr_nMagics = nMagics;
  791.     for( i = 0; i < nMagics; i++ )
  792.         ilr->ilr_magics[i] = magics[i];
  793.     (void)XR_MonitorEntry( &(XR_ilSymTab->ilst_ml) );
  794.     ilr->ilr_next = XR_ilSymTab->ilst_registrations;
  795.     XR_ilSymTab->ilst_registrations = ilr;
  796.     (void)XR_MonitorExit( &(XR_ilSymTab->ilst_ml) );
  797.     return 0;
  798. }
  799.  
  800.  
  801. static bool
  802. XR_ILMagicMatchesRegistration(ilr, m)
  803.     XR_ILRegistration ilr;
  804.     unsigned m;
  805. {
  806.     unsigned *p, *pLim;
  807.  
  808.     if( m == 0 ) return TRUE;
  809.     for( ((p = ilr->ilr_magics),(pLim = p + ilr->ilr_nMagics)); p < pLim; p++ )
  810.         if( *p == m ) return TRUE;
  811.     return FALSE;
  812. }
  813.  
  814.  
  815. /*
  816.  *
  817.  * Utilities for use by registered incremental loading procs
  818.  *
  819.  * Exported to IncrementalLoadPrivate.h
  820.  *
  821.  */
  822.  
  823. static struct XR_ILErrorRep XR_ilNoMemErrorRep = {
  824.     /* ile_fatal */    TRUE,
  825.     /* ile_code */    ENOMEM,
  826.     /* ile_msg */    "out of memory"
  827. };
  828.  
  829.  
  830. XR_ILError
  831. XR_ILMakeError(fatal, code, msg)
  832.     bool fatal;
  833.     int code;
  834.     char * msg;
  835. {
  836.     XR_ILError ile;
  837.  
  838.     ile = (XR_ILError) XR_malloc( sizeof(struct XR_ILErrorRep) );
  839.     if( ile == NIL ) return( &(XR_ilNoMemErrorRep) );
  840.     ile->ile_fatal = fatal;
  841.     ile->ile_code = code;
  842.     if( msg == NIL ) {
  843.         ile->ile_msg = "(no msg)";
  844.     } else {
  845.         ile->ile_msg = (char *) XR_malloc( strlen(msg)+1 );
  846.         if( ile->ile_msg == NIL ) {
  847.             ile->ile_msg = "(no memory for msg)";
  848.         } else {
  849.             strcpy(ile->ile_msg, msg);
  850.         }
  851.     }
  852.     return ile;
  853. }
  854.  
  855. XR_ILError
  856. XR_ILMakeNoMemError()
  857. {
  858.     /* put it in the heap if we can ... */
  859.     return XR_ILMakeError(TRUE, ENOMEM, "out of memory");
  860. }
  861.  
  862.  
  863.  
  864. void
  865. XR_ILGetOpenFile(ilst)
  866.     XR_ILSymTab ilst;
  867. {
  868.     if( ilst->ilst_fd != XR_nullFildes ) return;
  869.  
  870.     ilst->ilst_fd = XR_Open(
  871.             ilst->ilst_ilfte->ilfte_ilfe.ilfe_fName, O_RDONLY, 0 );
  872.     if( ilst->ilst_fd == XR_nullFildes ) {
  873.         XR_ILSetError(ilst, FALSE, XR_GetErrno(),
  874.             "ILGetOpenFile: open error");
  875.     } else {
  876.         struct stat b;
  877.         int ans = XR_FStat(ilst->ilst_fd, &b);
  878.         if( ans < 0 ) {
  879.             XR_ILSetError(ilst, FALSE, XR_GetErrno(),
  880.                 "ILGetOpenFile: stat error");
  881.         } else {
  882.             ilst->ilst_ilfte->ilfte_ilfe.ilfe_fSize = b.st_size;
  883.             ilst->ilst_ilfte->ilfte_ilfe.ilfe_fMTime = b.st_mtime;
  884.             (void)XR_SetGetBlocking(ilst->ilst_fd, XR_UIO_BLOCKING_ALL_DATA);
  885.         }
  886.     }
  887. }
  888.  
  889.  
  890. void
  891. XR_ILCloseFile(ilst)
  892.     XR_ILSymTab ilst;
  893. {
  894.     if( ilst->ilst_fd != XR_nullFildes ) {
  895.         (void) XR_Close(ilst->ilst_fd);
  896.         ilst->ilst_fd = XR_nullFildes;
  897.     }
  898. }
  899.  
  900.  
  901. #if (!PREEMPTABLE_READ)
  902.  
  903. void
  904. XR_ILRead(ilst, offset, buf, bytes, abortOnError)
  905.     XR_ILSymTab ilst;
  906.     unsigned offset;
  907.     char *buf;
  908.     unsigned bytes;
  909.     bool abortOnError;
  910. {
  911.     int ans;
  912.  
  913.     ans = XR_LSeek(ilst->ilst_fd,
  914.             offset+ilst->ilst_ilfte->ilfte_ilfe.ilfe_fOffset, L_SET);
  915.     if( ans < 0 ) goto Bad;
  916.     ans = XR_Read(ilst->ilst_fd, buf, bytes);
  917.     if( ans != bytes ) goto Bad;
  918.     return;
  919.   Bad:
  920.     XR_ILSetError(ilst, abortOnError, XR_GetErrno(), "ILRead: I/O error");
  921. }
  922.  
  923. #else
  924.  
  925. #define READALIGN 1024
  926. #define MAXREAD (16*1024)
  927.  
  928. void
  929. XR_ILRead(ilst, offset, buf, bytes, abortOnError)
  930.     XR_ILSymTab ilst;
  931.     unsigned offset;
  932.     char *buf;
  933.     unsigned bytes;
  934.     bool abortOnError;
  935. {
  936.     int ans, readreq;
  937.  
  938.     if( offset != ((unsigned)(-1)) ) {
  939.         ans = XR_LSeek(ilst->ilst_fd,
  940.                 offset+ilst->ilst_ilfte->ilfte_ilfe.ilfe_fOffset, L_SET);
  941.         if( ans < 0 ) goto Bad;
  942.     }
  943.     if( bytes == 0 ) return;
  944.     for(;;) {
  945.         if( (readreq = bytes) > MAXREAD )
  946.             readreq = MAXREAD - ( ((int)(buf)) & (READALIGN-1) );
  947.         ans = XR_Read(ilst->ilst_fd, buf, readreq);
  948.         if( ans < 0 ) goto Bad;
  949.         buf += ans;
  950.         if( (bytes -= ans) == 0 ) return;
  951.         if( ans == 0 ) goto Bad;
  952.     }
  953.   Bad:
  954.     XR_ILSetError(ilst, abortOnError, XR_GetErrno(), "ILRead: I/O error");
  955. }
  956.  
  957. #endif
  958.  
  959.  
  960. void
  961. XR_ILAllocSegments(ilst, tBytes, dBytes, bBytes)
  962.     XR_ILSymTab ilst;
  963.     unsigned tBytes;
  964.     unsigned dBytes;
  965.     unsigned bBytes;
  966. {
  967.     XR_ILFileEntry ilfe = &(ilst->ilst_ilfte->ilfte_ilfe);
  968.     unsigned pBytes = 0;
  969. #   define ROUNDUPDOUBLE(x) ((((unsigned)(x)) + 0x7) & (~0x7))
  970.  
  971.     ilfe->ilfe_tBytes = tBytes;
  972.     ilfe->ilfe_dBytes = dBytes;
  973.     ilfe->ilfe_bBytes = bBytes;
  974.     ilfe->ilfe_pBytes = pBytes;
  975.  
  976.     if( ilst->ilst_initializationState == ilis_internalizing ) {
  977.         ilfe->ilfe_tAddr = ((caddr_t)(0));
  978.         ilfe->ilfe_dAddr = ((caddr_t)(tBytes));
  979.         ilfe->ilfe_bAddr = ((caddr_t)(tBytes + dBytes));
  980.         ilfe->ilfe_pAddr = ((caddr_t)(NIL));
  981.         return;
  982.     }
  983.  
  984.     ilfe->ilfe_pBytes = ROUNDUPDOUBLE(256 + DEFAULT_PBYTES_FROM_TBYTES(tBytes));
  985.     if( ilst->ilst_activePatchSizeProc != NIL ) {
  986.         (*(ilst->ilst_activePatchSizeProc))(
  987.                 ilfe, ilst->ilst_activePatchSizeClientData );
  988.     }
  989.     ilfe->ilfe_pBytes = ROUNDUPDOUBLE(ilfe->ilfe_pBytes);
  990.     pBytes = ilfe->ilfe_pBytes;
  991.  
  992.     if( (pBytes + tBytes) > 0 ) {
  993.         ilfe->ilfe_pAddr = XR_PZmalloc( ilst->ilst_zonePtrFree,
  994.                 pBytes + tBytes );
  995.         XR_ILCheckAlloc2(ilst, ilfe->ilfe_pAddr);
  996.         ilfe->ilfe_tAddr = (caddr_t)
  997.                 ( ((unsigned)(ilfe->ilfe_pAddr)) + pBytes );
  998.         if( pBytes > 0 ) (void) bzero( ilfe->ilfe_pAddr, pBytes );
  999.     }
  1000.     if( dBytes > 0 ) {
  1001.         ilfe->ilfe_dAddr = XR_PZmalloc( ilst->ilst_zonePtrFree, dBytes );
  1002.         XR_ILCheckAlloc2(ilst, ilfe->ilfe_dAddr);
  1003.     }
  1004.     if( bBytes > 0 ) {
  1005.         ilfe->ilfe_bAddr = XR_PZcalloc( ilst->ilst_zonePtrFree, bBytes, 1 );
  1006.         XR_ILCheckAlloc2(ilst, ilfe->ilfe_bAddr);
  1007.     }
  1008. }
  1009.  
  1010.  
  1011. static void
  1012. XR_ILDoDeferredRelocation(ilst, ilste)
  1013.     XR_ILSymTab ilst;
  1014.     XR_ILSymTabEntry ilste;
  1015. {
  1016.     XR_ILRelocItem ilri;
  1017.  
  1018.     ilri = ilste->ilste_ilri;
  1019.     ilste->ilste_ilri = NIL;
  1020.     if( ilst->ilst_initializationState >= ilis_internalized ) {
  1021.         while( ilri != NIL ) {
  1022. #           ifdef UNIXDEBUG
  1023.                 printf("ILDRelocate %s ", ilste->ilste_ilse.ilse_name);
  1024.                 printf("addr 0x%x type 0x%x addend 0x%x val 0x%x\n",
  1025.                         ilri->ilri_addr, ilri->ilri_type, ilri->ilri_addend,
  1026.                         ilste->ilste_ilse.ilse_value);
  1027. #           endif
  1028.             (*ilri->ilri_proc) (
  1029.                 ilri->ilri_addr,
  1030.                 ilri->ilri_type,
  1031.                 ilri->ilri_addend,
  1032.                 ilste->ilste_ilse.ilse_value
  1033.             );
  1034.             ilri = ilri->ilri_next;
  1035.         }
  1036.     }
  1037. }
  1038.  
  1039.  
  1040. static void
  1041. XR_ILMoveDeferredRelocationItems(ilst, ilsteOld, ilsteNew)
  1042.     XR_ILSymTab ilst;
  1043.     XR_ILSymTabEntry ilsteOld;
  1044.     XR_ILSymTabEntry ilsteNew;
  1045. {
  1046.     XR_ILRelocItem ilri = NIL;
  1047.  
  1048.     if( ilst->ilst_initializationState < ilis_internalized ) return;
  1049.     if( ilsteOld != NIL ) {
  1050.         ilri = ilsteOld->ilste_ilri;
  1051.         ilsteOld->ilste_ilri = NIL;
  1052.     }
  1053.     if( ilsteNew != NIL ) {
  1054.         ilsteNew->ilste_ilri = ilri;
  1055.     }
  1056. }
  1057.  
  1058.  
  1059. XR_ILSymTabEntry
  1060. XR_ILSetSymDefined(ilst, sym, hash, symType, symValue, symSize)
  1061.     XR_ILSymTab ilst;
  1062.     char *sym;
  1063.     unsigned hash;
  1064.     unsigned symType;
  1065.     unsigned symValue;
  1066. {
  1067.     XR_ILSymTabEntry steOld;
  1068.     XR_ILSymTabEntry steNew;
  1069.     XR_ILContinueAction clientAction;
  1070.  
  1071. #   ifdef UNIXDEBUG
  1072.         if( ilst->ilst_initializationState >= ilis_internalized )
  1073.             printf("ILSetSymDefined(%s, 0x%x, 0x%x)\n", sym, symType, symValue);
  1074. #   endif
  1075.     steNew = XR_ILMakeSTE(ilst, sym, hash, symType, symValue, symSize);
  1076.     if( steNew == NIL ) return NIL;
  1077.     if( (symType & ILSE_EXT) == 0 ) {
  1078.         XR_ILInsertSTE(ilst, steNew);
  1079.         return steNew;
  1080.     }
  1081.     steOld = XR_ILLookupSTEByName(ilst, sym, hash,
  1082.             /*caseSensitive=*/ TRUE, /*externalOnly=*/ TRUE);
  1083.     clientAction = ilca_continue;
  1084.     if( ilst->ilst_activeDefProc != NIL ) {
  1085.         clientAction = (*(ilst->ilst_activeDefProc))(
  1086.             ((XR_ILSymEntry)(steNew)),
  1087.             ((XR_ILSymEntry)(steOld)),
  1088.             ilst->ilst_activeDefClientData
  1089.         );
  1090.     }
  1091.     if( clientAction == ilca_continue ) {
  1092.         clientAction = ( ((steOld != NIL) &&
  1093.                 (steOld->ilste_ilse.ilse_type == (ILSE_UNDF|ILSE_EXT))) 
  1094.             ? ilca_doBind : ilca_dontBind );
  1095.     }
  1096.     switch( clientAction ) {
  1097.         case ilca_doBind:
  1098.             if( (steOld != NIL) &&
  1099.                     (steOld->ilste_ilse.ilse_type == (ILSE_UNDF|ILSE_EXT)) ) {
  1100.                 if( steOld->ilste_ilse.ilse_size == 0 )
  1101.                     /* old symbol wasn't common */
  1102.                     ilst->ilst_numUndefined -= 1;
  1103.                 steOld->ilste_ilse.ilse_type = symType;
  1104.                 steOld->ilste_ilse.ilse_value = symValue;
  1105.                 steOld->ilste_ilse.ilse_size = symSize;
  1106.                 steOld->ilste_ilse.ilse_ilfe =
  1107.                         (XR_ILFileEntry) (ilst->ilst_ilfte);
  1108.                 return steOld;
  1109.             }
  1110.             XR_ILSetError(ilst, TRUE, XR_EABORTED,
  1111.                     "XR_ILSetSymDefined ilca_doBind error");
  1112.             return NIL;
  1113.         case ilca_dontBind:
  1114.             XR_ILMoveDeferredRelocationItems(ilst, steOld, steNew);
  1115.             XR_ILInsertSTE(ilst, steNew);
  1116.             return steNew;
  1117.         default:
  1118.             XR_ILSetError(ilst, TRUE, XR_EABORTED, clientAction);
  1119.             return NIL;
  1120.     }
  1121. }
  1122.  
  1123.  
  1124.  
  1125. XR_ILSymTabEntry
  1126. XR_ILSetSymCommon(ilst, sym, hash, size)
  1127.     XR_ILSymTab ilst;
  1128.     char *sym;
  1129.     unsigned hash;
  1130.     unsigned size;
  1131. {
  1132.     XR_ILSymTabEntry steOld, steNew;
  1133.     XR_ILContinueAction clientAction;
  1134.     
  1135. #   ifdef UNIXDEBUG
  1136.         if( ilst->ilst_initializationState >= ilis_internalized )
  1137.             printf("ILSetSymCommon(%s, %d)\n", sym, size);
  1138. #   endif
  1139.     steOld = XR_ILLookupSTEByName(ilst, sym, hash,
  1140.             /*caseSensitive=*/ TRUE, /*externOnly*/ TRUE);
  1141.     clientAction = ilca_continue;
  1142.     if( ilst->ilst_activeCommonProc != NIL ) {
  1143.         clientAction = (*(ilst->ilst_activeCommonProc))(
  1144.             sym,
  1145.             size,
  1146.             ((XR_ILSymEntry)(steOld)),
  1147.             ilst->ilst_activeCommonClientData
  1148.         );
  1149.     }
  1150.     if( clientAction == ilca_continue ) {
  1151.         clientAction = ((steOld == NIL) ? ilca_dontBind : ilca_doBind);
  1152.     }
  1153.     switch( clientAction ) {
  1154.         case ilca_dontBind:
  1155.             steNew = XR_ILMakeSTE( ilst, sym, hash,
  1156.                     (ILSE_UNDF|ILSE_EXT), 0, size );
  1157.             if( steNew != NIL ) {
  1158.                 XR_ILMoveDeferredRelocationItems(ilst, steOld, steNew);
  1159.                 XR_ILInsertSTE(ilst, steNew);
  1160.             }
  1161.             return steNew;
  1162.         case ilca_doBind:
  1163.             if( steOld != NIL ) {
  1164.                 if( steOld->ilste_ilse.ilse_type == (ILSE_UNDF|ILSE_EXT) ) {
  1165.                     if( steOld->ilste_ilse.ilse_size == 0 )
  1166.                         ilst->ilst_numUndefined -= 1;
  1167.                     if( steOld->ilste_ilse.ilse_size < size )
  1168.                         steOld->ilste_ilse.ilse_size = size;
  1169.                 }
  1170.                 return steOld;
  1171.             }
  1172.             XR_ILSetError(ilst, TRUE, XR_EABORTED,
  1173.                     "XR_ILSetSymCommon ilca_doBind error");
  1174.             return NIL;
  1175.         default:
  1176.             XR_ILSetError(ilst, TRUE, XR_EABORTED, clientAction);
  1177.             return NIL;
  1178.     }
  1179. }
  1180.  
  1181.  
  1182.  
  1183. XR_ILSymTabEntry
  1184. XR_ILSetSymReferenced(ilst, sym, hash)
  1185.     XR_ILSymTab ilst;
  1186.     char *sym;
  1187.     unsigned hash;
  1188. {
  1189.     XR_ILSymTabEntry steOld, steNew;
  1190.     XR_ILContinueAction clientAction;
  1191.  
  1192. #   ifdef UNIXDEBUG
  1193.         if( ilst->ilst_initializationState >= ilis_internalized )
  1194.             printf("ILSetSymReferenced(%s)\n", sym);
  1195. #   endif
  1196.  
  1197.     steOld = XR_ILLookupSTEByName(ilst, sym, hash,
  1198.             /*caseSensitive=*/ TRUE, /*externOnly*/ TRUE);
  1199.     clientAction = ilca_continue;
  1200.     if( ilst->ilst_activeRefProc != NIL ) {
  1201.         clientAction = (*(ilst->ilst_activeRefProc))(
  1202.             sym,
  1203.             ((XR_ILSymEntry)(steOld)),
  1204.             ilst->ilst_activeRefClientData
  1205.         );
  1206.     }
  1207.     if( clientAction == ilca_continue ) {
  1208.         clientAction = ((steOld == NIL) ? ilca_dontBind : ilca_doBind);
  1209.     }
  1210.     switch( clientAction ) {
  1211.         case ilca_dontBind:
  1212.             steNew = XR_ILMakeSTE( ilst, sym, hash,
  1213.                     (ILSE_UNDF|ILSE_EXT), 0, 0 );
  1214.             if( steNew != NIL ) {
  1215.                 XR_ILMoveDeferredRelocationItems(ilst, steOld, steNew);
  1216.                 XR_ILInsertSTE( ilst, steNew );
  1217.                 ilst->ilst_numUndefined += 1;
  1218.             }
  1219.             return steNew;
  1220.         case ilca_doBind:
  1221.             if( steOld != NIL ) return steOld;
  1222.             XR_ILSetError(ilst, TRUE, XR_EABORTED,
  1223.                     "XR_ILSetSymReferenced ilca_doBind error");
  1224.             return NIL;
  1225.         default:
  1226.             XR_ILSetError(ilst, TRUE, XR_EABORTED, clientAction);
  1227.             return NIL;
  1228.     }
  1229. }
  1230.  
  1231.  
  1232.  
  1233. void
  1234. XR_ILRelocate(ilst, ilste, proc, addr, relocType, addend)
  1235.     XR_ILSymTab ilst;
  1236.     XR_ILSymTabEntry ilste;
  1237.     void (*proc)(/*
  1238.         char *addr,
  1239.         unsigned relocType, long addend, unsigned val
  1240.     */);
  1241.     char *addr;
  1242.     unsigned relocType;
  1243.     long addend;
  1244. {
  1245.     XR_ILRelocItem ilri;
  1246.  
  1247.     if( ilst->ilst_initializationState >= ilis_internalized ) {
  1248. #       ifdef UNIXDEBUG
  1249.             printf("ILRelocate sym %s addr 0x%x type 0x%x addend 0x%x ... ",
  1250.                     ilste->ilste_ilse.ilse_name, addr, relocType, addend );
  1251. #       endif
  1252.         if( (ilste->ilste_ilse.ilse_type & ILSE_TYPE) != ILSE_UNDF ) {
  1253. #           ifdef UNIXDEBUG
  1254.                 printf("immediate 0x%x\n", ilste->ilste_ilse.ilse_value);
  1255. #           endif
  1256.             (*proc)(addr, relocType, addend, ilste->ilste_ilse.ilse_value);
  1257.         } else {
  1258.             XR_ILRelocItem ilri;
  1259. #           ifdef UNIXDEBUG
  1260.                 printf("deferred\n");
  1261. #           endif
  1262.             ilri = (XR_ILRelocItem) XR_PZmalloc(
  1263.                 ilst->ilst_zonePerCommit, sizeof(struct XR_ILRelocItemRep) );
  1264.             XR_ILCheckAlloc2(ilst, ilri)
  1265.             ilri->ilri_proc = proc;
  1266.             ilri->ilri_addr = addr;
  1267.             ilri->ilri_type = relocType;
  1268.             ilri->ilri_addend = addend;
  1269.             ilri->ilri_next = ilste->ilste_ilri;
  1270.             ilste->ilste_ilri = ilri;
  1271.         }
  1272.     }
  1273. }
  1274.  
  1275.  
  1276. static void XR_ILRecordCommon();
  1277. static void XR_ILRecordNewFiles();
  1278.  
  1279. /*
  1280.  * Insert new symbols preparatory to commit.
  1281.  * IMPORTANT: this either succeeds or has no effect. 
  1282.  */
  1283. static XR_ILError
  1284. XR_ILInsertNewSymbols(ilst)
  1285.     XR_ILSymTab ilst;
  1286. {
  1287.     XR_ILSymTabEntry ilste;
  1288.     unsigned disp, len, cBytes;
  1289.     caddr_t cAddr;
  1290.  
  1291. #   ifdef UNIXDEBUG
  1292.         printf("ILInsertNewSymbols\n");
  1293. #   endif
  1294.  
  1295.     /* if we're just internalizing symbols, skip common    */
  1296.     /* processing and relocation            */
  1297.         if( ilst->ilst_initializationState == ilis_internalizing ) {
  1298.             ilst->ilst_undefinedSymsHdCache = NIL;
  1299.             while( (ilste = ilst->ilst_newSymsHd) != NIL ) {
  1300.                 ilst->ilst_newSymsHd = ilste->ilste_valNext[0];
  1301.                 ilste->ilste_valNext[0] = NIL;
  1302.                 if( (ilste->ilste_ilse.ilse_type & ILSE_TYPE) != ILSE_ABS ) {
  1303.                     XR_ILInsertSTEByValue(ilst, ilste);
  1304.                 }
  1305.             }
  1306.             ilst->ilst_newSymsTl = NIL;
  1307.             return;
  1308.         }
  1309.  
  1310.     /* compute offsets in common seg for all common defs */
  1311.     /* compute size of common seg                        */
  1312.         disp = 0;
  1313.         for(
  1314.             ilste = ilst->ilst_newSymsHd;
  1315.             ilste != NIL;
  1316.             ilste = ilste->ilste_valNext[0]
  1317.         ) {
  1318.             if( ilste->ilste_ilse.ilse_type != (ILSE_UNDF|ILSE_EXT) )
  1319.                 continue;
  1320.             len = ilste->ilste_ilse.ilse_size;
  1321.             XR_ILAssert( (len > 0), "ILAllocateCommon a0" );
  1322.             if( len & 0x1 ) {
  1323.                 /* nothing */
  1324.             } else if( len & 0x3 ) {
  1325.                 disp = (disp + 0x1) & (~0x1);
  1326.             } else if( len & 0x7 ) {
  1327.                 disp = (disp + 0x3) & (~0x3);
  1328.             } else {
  1329.                 disp = (disp + 0x7) & (~0x7);
  1330.             }
  1331.             ilste->ilste_ilse.ilse_value = disp;
  1332.             disp += len;
  1333.         }
  1334.         cBytes = (disp + 0x7) & (~0x7);
  1335.  
  1336.     /* allocate common segment */
  1337.         cAddr = NIL;
  1338.         if( cBytes > 0 ) {
  1339.             cAddr = (caddr_t) XR_PZcalloc(ilst->ilst_zonePtrFree, cBytes, 1);
  1340.             XR_ILCheckAlloc(cAddr);
  1341.         }
  1342.         ilst->ilst_ilfte->ilfte_ilfe.ilfe_cBytes = cBytes;
  1343.         ilst->ilst_ilfte->ilfte_ilfe.ilfe_cAddr = cAddr;
  1344.  
  1345.     /* define common syms and do deferred relocation, insert syms by value */
  1346.         ilst->ilst_undefinedSymsHdCache = NIL;
  1347.         while( (ilste = ilst->ilst_newSymsHd) != NIL ) {
  1348.             ilst->ilst_newSymsHd = ilste->ilste_valNext[0];
  1349.             ilste->ilste_valNext[0] = NIL;
  1350.             if( ilste->ilste_ilse.ilse_type == (ILSE_UNDF|ILSE_EXT) ) {
  1351.                 ilste->ilste_ilse.ilse_type = (ILSE_BSS|ILSE_EXT);
  1352.                 ilste->ilste_ilse.ilse_value =
  1353.                         (unsigned) (cAddr + ilste->ilste_ilse.ilse_value);
  1354.                 XR_ILRecordCommon(ilst, ilste);
  1355.             }
  1356.             XR_ILDoDeferredRelocation(ilst, ilste); /* can't fail! */
  1357.             if( (ilste->ilste_ilse.ilse_type & ILSE_TYPE) != ILSE_ABS ) {
  1358.                 XR_ILInsertSTEByValue(ilst, ilste);
  1359.             }
  1360.         }
  1361.         ilst->ilst_newSymsTl = NIL;
  1362. }
  1363.  
  1364.  
  1365. static void
  1366. XR_ILDiscardNewSymbols(ilst)
  1367.     XR_ILSymTab ilst;
  1368. {
  1369.     XR_ILSymTabEntry ilste, *hp, *hpLim;
  1370.     unsigned sinceSeqNum;
  1371.  
  1372.     sinceSeqNum = ilst->ilst_ilfte->ilfte_ilfe.ilfe_seqNum;
  1373. #   ifdef UNIXDEBUG
  1374.         printf("ILDiscardNewSymbols(since: %d)\n", sinceSeqNum);
  1375. #   endif
  1376.     ilst->ilst_undefinedSymsHdCache = NIL;
  1377.     ilst->ilst_newSymsHd = NIL;
  1378.     ilst->ilst_newSymsTl = NIL;
  1379.     hp = ilst->ilst_hdrs;
  1380.     hpLim = hp + ilst->ilst_numHdrs;
  1381.     while( hp < hpLim ) {
  1382.         if( ((ilste = *hp) != NIL)
  1383.                 && (ilste->ilste_ilse.ilse_ilfe->ilfe_seqNum > sinceSeqNum) ) {
  1384.             XR_ILDeleteSTE(ilst, ilste);
  1385.         } else {
  1386.             hp++;
  1387.         }
  1388.     }
  1389.     ilst->ilst_numUndefined = 0;
  1390. }
  1391.  
  1392.  
  1393. /*
  1394.  *
  1395.  * Exported to IncrementalLoad.h
  1396.  *
  1397.  */
  1398.  
  1399. bool
  1400. XR_ILSymIsInRecentLoad(ilse)
  1401.     XR_ILSymEntry ilse;
  1402. {
  1403.     XR_ILFileTabEntry ilfte;
  1404.     unsigned seqNum;
  1405.  
  1406.     if( (ilse == NIL) || ((seqNum = ilse->ilse_ilfe->ilfe_seqNum) == 0) )
  1407.         return FALSE;    /* client error, really */
  1408.  
  1409.     ilfte = XR_ilSymTab->ilst_ilfte;
  1410.     for(;;) {
  1411.         if( seqNum >= ilfte->ilfte_ilfe.ilfe_seqNum )
  1412.             /* changed from > to >= April 6, 1990 ajd */
  1413.             return( TRUE );
  1414.         ilfte = ilfte->ilfte_prev;
  1415.         if( ilfte->ilfte_ilfe.ilfe_commitPoint )
  1416.             return( FALSE );
  1417.     }
  1418. }
  1419.  
  1420.  
  1421.  
  1422. XR_Pointer
  1423. XR_ILLookupProc(name, externOnly, recentOnly)
  1424.     char *name;
  1425.     bool externOnly;
  1426.     bool recentOnly;
  1427. {
  1428.     XR_ILSymEntry ilse;
  1429.     XR_Pointer procToCall = NIL;
  1430.  
  1431.     ilse = XR_ILGetMatchingSymEntryByName(
  1432.         /*ilse*/        NIL,
  1433.         /*pattern*/        name,
  1434.         /*caseSensitive*/    TRUE,
  1435.         /*wantedTypes*/        ILSE_TEXT,
  1436.         /*ignoredClasses*/    (externOnly ? IGNORE_INTERNAL : IGNORE_NONE),
  1437.         /*numToSkip*/        0
  1438.     );
  1439.     if( ilse != NIL ) {
  1440.         if( (!recentOnly) || XR_ILSymIsInRecentLoad(ilse) ) {
  1441.             procToCall = ((XR_Pointer)(ilse->ilse_value));
  1442.         }
  1443.     }
  1444.     return procToCall;
  1445. }
  1446.  
  1447.  
  1448.  
  1449. void
  1450. XR_ILEnumerateUndefinedSyms(func, clientData)
  1451.     bool (*func)(/*XR_SymEntry se, void *clientData*/);
  1452.     char *clientData;
  1453. {
  1454.     XR_ILSymTab ilst;
  1455.     XR_ILSymTabEntry ilste;
  1456.  
  1457.     ilst = XR_ilSymTab;
  1458.     if( ilst->ilst_numUndefined == 0 ) return;
  1459.     if( func == NIL ) return;
  1460.     if( (ilste = ilst->ilst_undefinedSymsHdCache) == NIL )
  1461.         ilste = ilst->ilst_newSymsHd;
  1462.     while( ilste != NIL ) {
  1463.         if( ((ilste->ilste_ilse.ilse_type & ILSE_TYPE) == ILSE_UNDF)
  1464.                 && (ilste->ilste_ilse.ilse_size == 0) ) {
  1465.             if( ilst->ilst_undefinedSymsHdCache == NIL )
  1466.                 ilst->ilst_undefinedSymsHdCache = ilste;
  1467.             if( !( (*func)(&(ilste->ilste_ilse), clientData) ) ) return;
  1468.         }
  1469.         ilste = ilste->ilste_valNext[0];
  1470.     }
  1471. }
  1472.  
  1473.  
  1474. static XR_ILError
  1475. XR_ILCallReaderProc(ilst, ilfte, op)
  1476.     XR_ILSymTab ilst;
  1477.     XR_ILFileTabEntry ilfte;
  1478.     XR_ILOp op;
  1479. {
  1480.     XR_ILReaderProc proc;
  1481.     XR_ILError theResult;
  1482.     XR_ILRegistration ilr;
  1483.  
  1484.     if( ilfte == NIL ) XR_Panic("ILCallReaderProc 0");
  1485.     if( (ilr = ilfte->ilfte_ilr) == NIL ) return NIL;
  1486.     if( (proc = ilr->ilr_proc) == NIL ) return NIL;
  1487.     ilst->ilst_opArg = op;
  1488.     ilst->ilst_ilfteArg = ilfte;
  1489.     ilst->ilst_result = NIL;
  1490.     ilst->ilst_readerProcData = ilr->ilr_data;
  1491.     (void) bzero(ilst->ilst_fileData, (sizeof ilst->ilst_fileData));
  1492.             /* not necessary, but ... */
  1493.     (*proc)(ilst);
  1494.     theResult = ilst->ilst_result;
  1495.     ilst->ilst_result = NIL;
  1496.     ilst->ilst_opArg = ilOpNone;
  1497.     ilst->ilst_ilfteArg = NIL;
  1498.     ilst->ilst_readerProcData = NIL;
  1499.     (void) bzero(ilst->ilst_fileData, (sizeof ilst->ilst_fileData));
  1500.     return theResult;
  1501. }
  1502.  
  1503. static void
  1504. XR_ILCommitFiles(ilst, ilfte)
  1505.     XR_ILSymTab ilst;
  1506.     XR_ILFileTabEntry ilfte;
  1507. {
  1508.     XR_ILError ile;
  1509.  
  1510.     if( ilfte == NIL ) XR_Panic("ILCommitFiles 0");
  1511.     if( ilfte->ilfte_ilfe.ilfe_commitPoint ) return;
  1512.     XR_ILCommitFiles(ilst, ilfte->ilfte_prev);
  1513.     ile = XR_ILCallReaderProc(ilst, ilfte, ilOpCommit);
  1514.     if( ile != NIL ) /* this is a reader proc bug */ {
  1515.         XR_ConsoleMsg("ILCommitFile %s error %s\n",
  1516.             ilfte->ilfte_ilfe.ilfe_fName, ile->ile_msg);
  1517.         XR_Panic("ILCommitFiles 1");
  1518.     }
  1519.     if( ilfte->ilfte_gcRootEnumerator == NIL ) {
  1520.         XR_ILSetGCRootEnumerator(
  1521.             ilst,
  1522.             ilfte,
  1523.             ( (ilst->ilst_initializationState >= ilis_internalized)
  1524.                 ? XR_ILDefaultGCRootEnumerator
  1525.                 : XR_ILDefaultBootFileGCRootEnumerator ),
  1526.             ((XR_Pointer)(ilfte))
  1527.         );
  1528.     }
  1529.     /* ??? INTERIM: if not internalizing, notify collector of new roots ??? */
  1530.     if( ilst->ilst_initializationState >= ilis_internalized )
  1531.         XR_ILTellCollectorAboutRoots(ilst, ilfte);
  1532. }
  1533.  
  1534.  
  1535. XR_ILError
  1536. XR_CommitIncrementalLoad()
  1537. {
  1538.     XR_ILSymTab ilst = XR_ilSymTab;
  1539.     XR_ILFileTabEntry ilfte = XR_ilSymTab->ilst_ilfte;
  1540.     XR_ILError result;
  1541.  
  1542.     if( ilst->ilst_numUndefined != 0 ) {
  1543.         return XR_ILMakeError(FALSE, EINVAL,
  1544.                 "CommitIncrementalLoad: undefined symbols exist");
  1545.     }
  1546.  
  1547.     result = XR_ILInsertNewSymbols(ilst);
  1548.     ilfte->ilfte_revertCookie = XR_PZremember(ilst->ilst_zone);
  1549.     ilfte->ilfte_revertCookiePtrFree = XR_PZremember(ilst->ilst_zonePtrFree);
  1550.     XR_ILCommitFiles(ilst, ilfte);
  1551.     XR_ILRecordNewFiles(ilst);
  1552.     ilfte->ilfte_ilfe.ilfe_commitPoint = TRUE;
  1553.     XR_PZrevert(ilst->ilst_zonePerCommit, XR_PZ_FREE_ALL);
  1554.     XR_PZrevert(ilst->ilst_zonePerFile, XR_PZ_FREE_ALL);
  1555.     return NIL;
  1556. }
  1557.  
  1558.  
  1559. static void
  1560. XR_ILDiscardActiveLoads(ilst, target)
  1561.     XR_ILSymTab ilst;
  1562.     XR_ILFileTabEntry target;
  1563. {
  1564.     XR_ILFileTabEntry ilfte;
  1565.     bool sawTarget;
  1566.     XR_ILRegistration ilr;
  1567.     XR_ILReaderProc proc;
  1568.  
  1569.     sawTarget = (target == NIL);
  1570. XR_LogVMsg "DiscardActiveLoads target 0x%x\n", target);
  1571.     ilfte = ilst->ilst_ilfte;
  1572.     for(;;) {
  1573.         if( ilfte == NIL ) break;
  1574.         if( (ilfte->ilfte_ilfe.ilfe_commitPoint) && sawTarget ) break;
  1575.         (void)XR_ILCallReaderProc(ilst, ilfte, ilOpAbort);
  1576.         if( ilfte == target ) sawTarget = TRUE;
  1577.         ilfte = ilfte->ilfte_prev;
  1578.     }
  1579.     ilst->ilst_ilfte = ilfte;
  1580.  
  1581. XR_LogVMsg "DiscardActiveLoads about to discard symbols ...\n");
  1582.     XR_ILDiscardNewSymbols(ilst);
  1583. XR_LogVMsg "DiscardActiveLoads about to free memory ...\n");
  1584.     XR_PZrevert(ilst->ilst_zone, ilfte->ilfte_revertCookie);
  1585.     XR_PZrevert(ilst->ilst_zonePtrFree, ilfte->ilfte_revertCookiePtrFree);
  1586.     XR_PZrevert(ilst->ilst_zonePerFile, XR_PZ_FREE_ALL);
  1587.     XR_PZrevert(ilst->ilst_zonePerCommit, XR_PZ_FREE_ALL);
  1588. XR_LogVMsg "DiscardActiveLoads done\n");
  1589. }
  1590.  
  1591.  
  1592. XR_ILError
  1593. XR_AbortIncrementalLoad(ilfe)
  1594.     XR_ILFileEntry ilfe;
  1595. {
  1596.     XR_ILSymTab ilst = XR_ilSymTab;
  1597.     XR_ILDiscardActiveLoads( ilst, ((XR_ILFileTabEntry)(ilfe)) );
  1598.     return NIL;
  1599. }
  1600.  
  1601.  
  1602. XR_ILError
  1603. XR_ILLoadFile(fName, fOffset, fMagic,
  1604.         refProc, refClientData, defProc, defClientData,
  1605.         commonProc, commonClientData, patchSizeProc, patchSizeClientData)
  1606.     char *fName;
  1607.     long fOffset;
  1608.     unsigned fMagic;
  1609.     XR_ILContinueAction (*refProc)(/*
  1610.         char *sym,
  1611.         XR_ILSymEntry ilseOld,
  1612.         void *clientData
  1613.     */);
  1614.     char *refClientData;
  1615.     XR_ILContinueAction (*defProc)(/*
  1616.         XR_ILSymEntry ilseNew,
  1617.         XR_ILSymEntry ilseOld,
  1618.         void *clientData
  1619.     */);
  1620.     char *defClientData;
  1621.     XR_ILContinueAction (*commonProc)(/*_
  1622.         char *sym,
  1623.         unsigned size,
  1624.         XR_ILSymEntry ilseOld,
  1625.         void *clientData
  1626.     */);
  1627.     char *commonClientData;
  1628.     void (*patchSizeProc)(/*
  1629.         XR_ILFileEntry ilfe,
  1630.         void *clientData
  1631.     */);
  1632.     char *patchSizeClientData;
  1633. {
  1634.     XR_ILSymTab ilst = XR_ilSymTab;
  1635.     XR_ILRegistration ilr;
  1636.     XR_ILFileTabEntry ilfte;
  1637.     XR_ILError theResult = NIL;
  1638.  
  1639.     if( ilst == NIL ) XR_Panic("XR_ILLoadFile 0");
  1640.     if( ilst->ilst_initializationState < ilis_internalizing ) {
  1641.         return XR_ILMakeError( TRUE, EINVAL,
  1642.                 "ILLoadFile: uninitialized" );
  1643.     }
  1644.     if( ilst->ilst_fd != (-1) ) XR_Panic("XR_ILLoadFile 1");
  1645.     ilst->ilst_fd = -1; /* redundant ??? */
  1646.  
  1647.     /*
  1648.      * Set up ...
  1649.      */
  1650.  
  1651.     /* create file table entry */
  1652.         ilfte = XR_ILCreateILFTE(ilst, fName, fOffset);
  1653.         XR_ILCheckAlloc(ilfte);
  1654.         ilfte->ilfte_prev = ilst->ilst_ilfte;
  1655.         ilst->ilst_ilfte = ilfte;
  1656.     /* store callbacks for reader proc */
  1657.         ilst->ilst_activeRefProc = refProc;
  1658.         ilst->ilst_activeRefClientData = refClientData;
  1659.         ilst->ilst_activeDefProc = defProc;
  1660.         ilst->ilst_activeDefClientData = defClientData;
  1661.         ilst->ilst_activeCommonProc = commonProc;
  1662.         ilst->ilst_activeCommonClientData = commonClientData;
  1663.         ilst->ilst_activePatchSizeProc = patchSizeProc;
  1664.         ilst->ilst_activePatchSizeClientData = patchSizeClientData;
  1665.  
  1666.     /*
  1667.      * Try each registered reader in turn ...
  1668.      */
  1669.  
  1670.     for(
  1671.         ilr = XR_ilSymTab->ilst_registrations;
  1672.         ilr != NIL;
  1673.         ilr = ilr->ilr_next
  1674.     ) {
  1675.         if( !XR_ILMagicMatchesRegistration(ilr, fMagic) ) continue;
  1676.         /* store reader proc id in file table */
  1677.             ilfte->ilfte_ilfe.ilfe_fMagic = fMagic;
  1678.             ilfte->ilfte_ilr = ilr;
  1679.             ilfte->ilfte_readerPrivateState = NIL;
  1680.         /* call the proc */
  1681.             theResult = XR_ILCallReaderProc(
  1682.                 ilst,
  1683.                 ilfte,
  1684.                 ( (ilst->ilst_initializationState >= ilis_internalized)
  1685.                         ? ilOpLoad
  1686.                         :  ilOpInternalize)
  1687.             );
  1688.         /* if successful, break */
  1689.             if( theResult == NIL ) goto Done;
  1690.         /* reader proc failed ... remove reader proc id from file table */
  1691.             ilfte->ilfte_ilr = NIL;
  1692.             ilfte->ilfte_readerPrivateState = NIL;
  1693.         /* analyze failure code to decide whether to continue or abort */
  1694.             if( theResult->ile_fatal ) goto Done;
  1695.             switch( theResult->ile_code ) {
  1696.               /* errors specific to this load proc */
  1697.                 case EDOM:
  1698.                     /* "domain error" -- magic was 0, but I can't parse file */
  1699.                     continue;
  1700.                 case ENOEXEC:
  1701.                     /* "no exec" -- file not specified format, or garbage */
  1702.                     goto Done;
  1703.               /* errors that all load procs may encounter */
  1704.                 case ENOENT:
  1705.                 case EACCES:
  1706.                     goto Done;
  1707.               /* unknown errors */
  1708.                 default:
  1709.                     continue;
  1710.             }
  1711.     }
  1712.     /* fell thru -- didn't find applicable loader */
  1713.         theResult = XR_ILMakeError(FALSE, EINVAL,
  1714.                 "ILLoadFile: unknown file type");
  1715.  
  1716.     /*
  1717.      * Done -- success or hard failure ...
  1718.      */
  1719.  
  1720.   Done:
  1721.  
  1722.     /* close file if open */
  1723.         XR_ILCloseFile(ilst);
  1724.     /* clean up reader proc callbacks */
  1725.         ilst->ilst_activeRefProc = NIL;
  1726.         ilst->ilst_activeRefClientData = NIL;
  1727.         ilst->ilst_activeDefProc = NIL;
  1728.         ilst->ilst_activeDefClientData = NIL;
  1729.         ilst->ilst_activeCommonProc = NIL;
  1730.         ilst->ilst_activeCommonClientData = NIL;
  1731.         ilst->ilst_activePatchSizeProc = NIL;
  1732.         ilst->ilst_activePatchSizeClientData = NIL;
  1733.     /* discard data from unsuccessful loads */
  1734.         if( theResult != NIL ) {
  1735.             if( theResult->ile_fatal ) {
  1736.                 XR_ILDiscardActiveLoads(ilst, NIL);
  1737.             } else {
  1738.                 ilst->ilst_ilfte = ilst->ilst_ilfte->ilfte_prev;
  1739.             }
  1740.         }
  1741.     /* free temporary space */
  1742.         XR_PZrevert(ilst->ilst_zonePerFile, XR_PZ_FREE_ALL);
  1743.  
  1744.     return theResult;
  1745. }
  1746.  
  1747.  
  1748. static void XR_ILInitInfoFile();
  1749.  
  1750. /*
  1751.  * Start of the world ...
  1752.  */
  1753.  
  1754. XR_ILError
  1755. XR_InitializeIncrementalLoader(fName)
  1756.     char *fName;
  1757. {
  1758.     extern void XR_run_IncrementalLoadDEFAULT();
  1759.  
  1760.     XR_ILError theResult = NIL;
  1761.     XR_ILSymTab ilst = XR_ilSymTab;
  1762.     XR_ILFileTabEntry ilfte;
  1763.     XR_ILSymTabEntry ilste;
  1764.  
  1765.     if( ilst->ilst_initializationState == ilis_initial ) {
  1766.         /* finish initialization of *ilst */
  1767.         XR_InitializeMonitor(&(ilst->ilst_ml));
  1768.         XR_InitializeCondition(&(ilst->ilst_avail), XR_WAIT_FOREVER);
  1769.         XR_EnableAborts(&(ilst->ilst_avail));
  1770.         ilst->ilst_numHdrs = XR_ILST_INIT_NUM_HDRS;
  1771.         ilst->ilst_hdrs = (XR_ILSymTabEntry *) XR_calloc(
  1772.                 XR_ILST_INIT_NUM_HDRS * sizeof(XR_ILSymTabEntry), 1 );
  1773.         XR_ILCheckAlloc( ilst->ilst_hdrs );
  1774.         ilfte = XR_ILCreateILFTE(ilst, NIL, 0);
  1775.         XR_ILCheckAlloc( ilfte );
  1776.         ilfte->ilfte_ilfe.ilfe_commitPoint = TRUE;
  1777.         ilfte->ilfte_revertCookie = XR_PZ_FREE_ALL;
  1778.         ilfte->ilfte_revertCookiePtrFree = XR_PZ_FREE_ALL;
  1779.         ilst->ilst_ilfte = ilfte;
  1780.         ilste = (XR_ILSymTabEntry) XR_calloc(
  1781.                 XR_ILSymTabEntryBytes(MAXHEIGHT), 1 );
  1782.         XR_ILCheckAlloc( ilste );
  1783.         ilste->ilste_height = MAXHEIGHT;
  1784.         ilste->ilste_ilse.ilse_ilfe = ((XR_ILFileEntry)(ilfte));
  1785.         ilst->ilst_left = ilste;
  1786.         ilst->ilst_fd = -1;
  1787.         ilst->ilst_zonePerFile = XR_PZCreate(FALSE, 0);
  1788.         XR_ILCheckAlloc( ilst->ilst_zonePerFile );
  1789.         ilst->ilst_zonePerCommit = XR_PZCreate(FALSE, 0);
  1790.         XR_ILCheckAlloc( ilst->ilst_zonePerCommit );
  1791.         ilst->ilst_zone = XR_PZCreate(FALSE, 0);
  1792.         XR_ILCheckAlloc( ilst->ilst_zone );
  1793.         ilst->ilst_zonePtrFree = XR_PZCreate(TRUE, 0);
  1794.         XR_ILCheckAlloc( ilst->ilst_zonePtrFree );
  1795.         XR_ILInitInfoFile(ilst);
  1796.         ilst->ilst_initializationState = ilis_allocated;
  1797.     }
  1798.  
  1799.     XR_run_IncrementalLoadDEFAULT();
  1800.  
  1801.     theResult = XR_LockIncrementalLoadState(TRUE);
  1802.     if( theResult != NIL ) return theResult;
  1803.  
  1804.     if( fName == NIL ) XR_Panic("InitializeIncrementalLoader 0");
  1805.  
  1806.     ilst->ilst_initializationState = ilis_internalizing;
  1807.     theResult = XR_ILLoadFile(
  1808.             /* file name */ fName,
  1809.             /* offset */ 0,
  1810.             /* fMagic */ 0,
  1811.             /* refProc */ NIL,
  1812.             /* refClientData */
  1813.             /* defProc */ NIL,
  1814.             /* defClientData */ NIL,
  1815.             /* commonProc */ NIL,
  1816.             /* commonClientData */ NIL,
  1817.             /* patchSizeProc */ NIL,
  1818.             /* patchSizeClientData */ NIL
  1819.     );
  1820.     if( theResult == NIL ) {
  1821.         theResult = XR_CommitIncrementalLoad();
  1822.         ilst->ilst_initializationState = ilis_internalized;
  1823.     }
  1824.     if( theResult != NIL ) {
  1825.         (void) XR_AbortIncrementalLoad();
  1826.         ilst->ilst_initializationState = ilis_allocated;
  1827.         theResult->ile_fatal = TRUE;
  1828.     }
  1829.  
  1830.     (void) XR_UnlockIncrementalLoadState();
  1831.     return theResult;
  1832. }
  1833.  
  1834.  
  1835. /*
  1836.  * Setup -- called before virtual processors are forked
  1837.  */
  1838.  
  1839. XR_ILSymTab XR_ilSymTab = NIL;
  1840.  
  1841. void
  1842. XR_SetupIncrementalLoader()
  1843. {
  1844.     XR_ILSymTab ilst;
  1845.  
  1846.     /*
  1847.      * allocate symbol table struct
  1848.      *
  1849.      * leave remaining initialization to XR_InitializeIncrementalLoader()
  1850.      */
  1851.     ilst = (XR_ILSymTab)
  1852.             XR_AllocSharedSysMem( sizeof(struct XR_ILSymTabRep) );
  1853.     (void) bzero( ilst, sizeof(struct XR_ILSymTabRep) );
  1854.     XR_ilSymTab = ilst;
  1855. }
  1856.  
  1857. /*
  1858.  * dbx initialization file
  1859.  */
  1860.  
  1861. static void
  1862. XR_ILRecordCommon(ilst, ilste)
  1863.     XR_ILSymTab ilst;
  1864.     XR_ILSymTabEntry ilste;
  1865. {
  1866.     /* write the entry for the common symbol in the file-and-commons-info */
  1867.     if (ilst->ilst_infoFile == -1) return;
  1868.     XR_Msg(ilst->ilst_infoFile, "C: %x %s\n",
  1869.         ilste->ilste_ilse.ilse_value,
  1870.         ilste->ilste_ilse.ilse_name );
  1871. }
  1872.  
  1873. static void
  1874. XR_ILRecordNewFiles(ilst)
  1875.     XR_ILSymTab ilst;
  1876. {
  1877.     /* write the entry for the new files in the file-and-commons-info */
  1878.     XR_ILFileTabEntry ilfte;
  1879.     XR_Fildes fd;
  1880.     if ((fd = ilst->ilst_infoFile) == -1) return;
  1881.     ilfte = ilst->ilst_ilfte;
  1882.     while( !(ilfte->ilfte_ilfe.ilfe_commitPoint) ) {
  1883.         /* write the record for ilfte */
  1884.         XR_Msg(fd, "F: %x %x %x %x %s\n", 
  1885.             ilfte->ilfte_ilfe.ilfe_tAddr,
  1886.             ilfte->ilfte_ilfe.ilfe_dAddr,
  1887.             ilfte->ilfte_ilfe.ilfe_bAddr,
  1888.             ilfte->ilfte_ilfe.ilfe_fOffset,
  1889.             ilfte->ilfte_ilfe.ilfe_fName );
  1890.         ilfte = ilfte->ilfte_prev;
  1891.     }
  1892.     
  1893. }
  1894.  
  1895. void
  1896. XR_ILGetInfoFileName(buf)
  1897.     char *buf;
  1898. {
  1899.     char *(XR_get_loader_directory());
  1900.     int XR_GetPID();
  1901.  
  1902.     XR_SPrintF(buf, "%s/ILsymtab.pid%d", 
  1903.             XR_get_loader_directory(), XR_GetPID() );
  1904. }
  1905.  
  1906. static void
  1907. XR_ILCleanUpInfoFile(name)
  1908.     char *name;
  1909. {
  1910.     (void)unlink(name);
  1911. }
  1912.  
  1913. static void (*XR_ilCleanUpInfoFile) = XR_ILCleanUpInfoFile;
  1914.  
  1915. static void
  1916. XR_ILInitInfoFile(ilst)
  1917.      XR_ILSymTab ilst;
  1918. {
  1919.     char *name = (char *) XR_pointerfree_new(256);
  1920.     XR_ILGetInfoFileName(name);
  1921.     ilst->ilst_infoFileName = name;
  1922.     if ((ilst->ilst_infoFile = 
  1923.         XR_Open(name, O_RDWR | O_TRUNC | O_CREAT, 0777)) < 0) {
  1924.         ilst->ilst_infoFile = -1;
  1925.     }
  1926.     (void)XR_RegisterTerminationCleanupProc(
  1927.         &XR_ilCleanUpInfoFile, name );
  1928. }  /* XR_ILInitInfoFile */
  1929.  
  1930.